#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: xjx
@time: 2023/11/2 15:24 
@file: data_description.py
@project: nanchangproject
@describe: 产生数据描述性信息，如平均值，中位数等等
"""
import math
import time

import numpy as np
import sys
import os
import django

sys.path.append('../../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nanchangproject.settings')
django.setup()  # 很关键的配置，必须先setup在导入models类

from drivinginfo.models import DataFields, DataDescription, BasicInfo, Drivinginfo
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Sum, Avg, Max, Min


def description_to_database(mean: float, count: int, vin: str, field_name: str, month: int, year: int,
                            median: float = 0):
    """
    @param mean: 平均值
    @param median: 中位数
    @param count: 有效数据量
    @param vin: 汽车的唯一标识码
    @param field_name: 字段名称
    @param month: 统计月份
    @param year: 统计年份
    @return:
    """
    try:
        data_field_instance = DataFields.objects.get(field_name=field_name)
    except ObjectDoesNotExist:
        data_field_instance = DataFields.objects.create(field_name=field_name)
    try:
        basic_info_instance = BasicInfo.objects.get(vin=vin)
    except ObjectDoesNotExist:
        basic_info_instance = BasicInfo.objects.create(vin=vin)
    DataDescription.objects.create(
        basic_info=basic_info_instance,
        field=data_field_instance,
        mean=mean,
        median=median,
        count=count,
        month=month,
        year=year,
    )
    print(f'{vin}数据{year}年{month}月，字段{field_name}的统计数据写入成功')


class DescriptionMaker(object):
    def __init__(self, year, month, mean, count, median=0):
        self.year = year
        self.month = month
        self.mean = mean
        self.count = count
        self.median = median


def create_description(vin: str, field_name: str):
    # 使用filter不会报错，找不到只会返回空列表
    # 部分日期数据有错误会从2023年跳到2003年和2008年
    query = Drivinginfo.objects.filter(vin=vin)
    max_time = query.aggregate(Max('data_time'))
    min_time = query.aggregate(Min('data_time'))
    max_year = list(max_time.values())[0].year  # int类型
    min_year = list(min_time.values())[0].year
    des_result_list = []
    year_iterator = min_year
    while True:
        for month_iterator in range(1, 13):
            filter_query = query.filter(data_time__year=year_iterator).filter(data_time__month=month_iterator)
            mean = filter_query.aggregate(Avg(field_name))
            # {'car_speed__avg': Decimal('30.7233917120600')}
            count = filter_query.count()
            mean_value = list(mean.values())[0]
            if count < 10:
                # 当统计数据小于10条时，认为是ECU日期出错
                continue
            # if not mean_value 不能这么写，因为[]/0/None在python中都是否的含义
            if mean_value is None:
                continue
            des_result_list.append(DescriptionMaker(
                year=year_iterator,
                month=month_iterator,
                mean=mean_value,
                count=count
            ))
            print(f'正在计算车辆{vin}的{year_iterator}年{month_iterator}月的{field_name}字段的平均值以及有效数据量')
        year_iterator += 1
        if year_iterator > max_year:
            break
    for item in des_result_list:
        description_to_database(
            vin=vin,
            field_name=field_name,
            mean=item.mean,
            count=item.count,
            year=item.year,
            month=item.month
        )


if __name__ == '__main__':
    vin_list = BasicInfo.objects.all()
    field_list = DataFields.objects.all()
    for vin_item in vin_list:
        for field_item in field_list:
            create_description(vin=vin_item.vin, field_name=field_item.field_name)
